"""
数据源管理API端点
提供数据源的CRUD操作、连接测试、批量操作等RESTful接口
"""

from fastapi import APIRouter, Depends, HTTPException, status, Query, Body
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Optional, List

from app.core.database import get_db
from app.core.dependencies import get_current_active_user
from app.models.auth import User
from app.models.datasource import DatabaseType, TestStatus
from app.schemas.datasource import (
    DataSourceCreate, DataSourceUpdate, DataSourceResponse, DataSourceListResponse,
    ConnectionTestRequest, ConnectionTestResponse, TestLogResponse,
    BatchTestRequest, BatchTestResponse, DataSourceStats,
    BatchOperationRequest
)
from app.schemas.common import BaseResponse
from app.services.datasource_service import datasource_service
from app.services.permission_hierarchy_service import require_resource_action
from app.core.logger import logger

router = APIRouter()


@router.get("", response_model=BaseResponse[DataSourceListResponse])
async def get_datasources(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=100, description="每页大小"),
    search: Optional[str] = Query(None, description="搜索关键词"),
    db_type: Optional[DatabaseType] = Query(None, description="数据库类型"),
    is_active: Optional[bool] = Query(None, description="是否启用"),
    test_status: Optional[TestStatus] = Query(None, description="测试状态"),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_resource_action("datasource", "view"))
):
    """
    获取数据源列表
    
    支持分页、搜索和筛选：
    - **page**: 页码（从1开始）
    - **page_size**: 每页大小（1-100）
    - **search**: 按名称、显示名称、主机地址搜索
    - **db_type**: 按数据库类型筛选
    - **is_active**: 按启用状态筛选
    - **test_status**: 按测试状态筛选
    """
    try:
        result = await datasource_service.get_datasources(
            db=db,
            page=page,
            page_size=page_size,
            search=search,
            db_type=db_type,
            is_active=is_active,
            test_status=test_status,
            current_user=current_user
        )
        
        return BaseResponse(
            data=result,
            message="获取数据源列表成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取数据源列表失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取数据源列表失败"
        )


@router.post("", response_model=BaseResponse[DataSourceResponse])
async def create_datasource(
    datasource_data: DataSourceCreate,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_resource_action("datasource", "create"))
):
    """
    创建数据源
    
    - **name**: 数据源名称（唯一标识）
    - **display_name**: 显示名称
    - **description**: 数据源描述（可选）
    - **type**: 数据库类型
    - **host**: 主机地址
    - **port**: 端口号
    - **database_name**: 数据库名称
    - **username**: 用户名
    - **password**: 密码（将被加密存储）
    - **connection_params**: 额外连接参数（可选）
    - **is_active**: 是否启用
    - **connection_timeout**: 连接超时时间（秒）
    - **max_connections**: 最大连接数
    """
    try:
        result = await datasource_service.create_datasource(
            db=db,
            datasource_data=datasource_data,
            current_user=current_user
        )
        
        return BaseResponse(
            data=result,
            message="数据源创建成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"创建数据源失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="创建数据源失败"
        )


@router.get("/{datasource_id}", response_model=BaseResponse[DataSourceResponse])
async def get_datasource(
    datasource_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_resource_action("datasource", "view"))
):
    """
    获取数据源详情
    
    - **datasource_id**: 数据源ID
    """
    try:
        result = await datasource_service.get_datasource_by_id(
            db=db,
            datasource_id=datasource_id,
            current_user=current_user
        )
        
        return BaseResponse(
            data=result,
            message="获取数据源详情成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取数据源详情失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取数据源详情失败"
        )


@router.put("/{datasource_id}", response_model=BaseResponse[DataSourceResponse])
async def update_datasource(
    datasource_id: int,
    datasource_data: DataSourceUpdate,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_resource_action("datasource", "update"))
):
    """
    更新数据源
    
    - **datasource_id**: 数据源ID
    - 其他字段为可选更新字段
    """
    try:
        result = await datasource_service.update_datasource(
            db=db,
            datasource_id=datasource_id,
            datasource_data=datasource_data,
            current_user=current_user
        )
        
        return BaseResponse(
            data=result,
            message="数据源更新成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"更新数据源失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="更新数据源失败"
        )


@router.delete("/{datasource_id}", response_model=BaseResponse[dict])
async def delete_datasource(
    datasource_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_resource_action("datasource", "delete"))
):
    """
    删除数据源（软删除）
    
    - **datasource_id**: 数据源ID
    """
    try:
        result = await datasource_service.delete_datasource(
            db=db,
            datasource_id=datasource_id,
            current_user=current_user
        )
        
        return BaseResponse(
            data=result,
            message="数据源删除成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"删除数据源失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="删除数据源失败"
        )


@router.post("/test", response_model=BaseResponse[ConnectionTestResponse])
async def test_connection_params(
    test_request: ConnectionTestRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_resource_action("datasource", "test"))
):
    """
    测试连接参数
    
    用于在创建或编辑数据源时测试连接参数是否正确
    """
    try:
        result = await datasource_service.test_connection_params(
            db=db,
            test_request=test_request,
            current_user=current_user
        )
        
        return BaseResponse(
            data=result,
            message="连接测试完成",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"测试连接参数失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="测试连接参数失败"
        )


@router.post("/{datasource_id}/test", response_model=BaseResponse[ConnectionTestResponse])
async def test_datasource_connection(
    datasource_id: int,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_resource_action("datasource", "test"))
):
    """
    测试数据源连接
    
    - **datasource_id**: 数据源ID
    """
    try:
        result = await datasource_service.test_datasource_connection(
            db=db,
            datasource_id=datasource_id,
            current_user=current_user
        )
        
        return BaseResponse(
            data=result,
            message="数据源连接测试完成",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"测试数据源连接失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="测试数据源连接失败"
        )


@router.post("/batch-test", response_model=BaseResponse[BatchTestResponse])
async def batch_test_datasources(
    request: BatchTestRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_resource_action("datasource", "test"))
):
    """
    批量测试数据源连接

    - **datasource_ids**: 数据源ID列表（最多50个）
    """
    try:
        result = await datasource_service.batch_test_datasources(
            db=db,
            request=request,
            current_user=current_user
        )

        return BaseResponse(
            data=result,
            message="批量连接测试完成",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"批量测试数据源失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="批量测试数据源失败"
        )


@router.post("/batch-delete", response_model=BaseResponse[dict])
async def batch_delete_datasources(
    request: BatchOperationRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_resource_action("datasource", "delete"))
):
    """
    批量删除数据源

    - **datasource_ids**: 数据源ID列表（最多50个）
    - **operation**: 必须为 "delete"
    """
    try:
        if request.operation != "delete":
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="操作类型必须为 delete"
            )

        result = await datasource_service.batch_delete_datasources(
            db=db,
            datasource_ids=request.datasource_ids,
            current_user=current_user
        )

        return BaseResponse(
            data=result,
            message="批量删除完成",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"批量删除数据源失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="批量删除数据源失败"
        )


@router.post("/batch-toggle", response_model=BaseResponse[dict])
async def batch_toggle_datasources(
    request: BatchOperationRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_resource_action("datasource", "update"))
):
    """
    批量启用/禁用数据源

    - **datasource_ids**: 数据源ID列表（最多50个）
    - **operation**: "enable" 或 "disable"
    """
    try:
        if request.operation not in ["enable", "disable"]:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="操作类型必须为 enable 或 disable"
            )

        is_active = request.operation == "enable"

        result = await datasource_service.batch_toggle_datasources(
            db=db,
            datasource_ids=request.datasource_ids,
            is_active=is_active,
            current_user=current_user
        )

        return BaseResponse(
            data=result,
            message="批量操作完成",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"批量操作数据源失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="批量操作数据源失败"
        )


@router.get("/stats", response_model=BaseResponse[DataSourceStats])
async def get_datasource_stats(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_resource_action("datasource", "view"))
):
    """
    获取数据源统计信息

    包括总数、活跃数、健康状态、类型分布等统计数据
    """
    try:
        result = await datasource_service.get_datasource_stats(
            db=db,
            current_user=current_user
        )

        return BaseResponse(
            data=result,
            message="获取统计信息成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取数据源统计失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取数据源统计失败"
        )


@router.get("/{datasource_id}/test-logs", response_model=BaseResponse[dict])
async def get_datasource_test_logs(
    datasource_id: int,
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=100, description="每页大小"),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(require_resource_action("datasource", "view"))
):
    """
    获取数据源测试日志

    - **datasource_id**: 数据源ID
    - **page**: 页码
    - **page_size**: 每页大小
    """
    try:
        result = await datasource_service.get_datasource_test_logs(
            db=db,
            datasource_id=datasource_id,
            page=page,
            page_size=page_size,
            current_user=current_user
        )

        return BaseResponse(
            data=result,
            message="获取测试日志成功",
            success=True
        )
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取测试日志失败：{str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取测试日志失败"
        )
